<template>
  <div>
    <el-tag
      @click="changeTag(item)"
      v-for="(item, i) in list"
      :key="i"
      :type="cur == item ? 'success' : ''"
    >
      {{ item }}
    </el-tag>
  </div>
  <el-input v-model="filterText" placeholder="查询函数" clearable />
  <div class="tree">
    <el-tree
      ref="tree"
      :data="data"
      :props="defaultProps"
      default-expand-all
      :filter-node-method="filterNode"
    >
      <template v-slot:default="{ node }">
        <element-tree-line :node="node" :showLabelLine="true">
          <template v-slot:node-label>
            <span style="font-size: 12px" @click="copy(node.label)">
              {{ node.label }}
              <i class="el-icon-eleme"></i
            ></span>
          </template>
        </element-tree-line>
      </template>
    </el-tree>
  </div>
</template>
<script>
// https://blog.csdn.net/cn_zgt_boss/article/details/121049766
import service from "../../common/api.js";
import * as vue from "vue";
window.vue = vue;

function short(arr) {
  return arr
    .filter((e) => e.label != +e.label)
    .sort((a, b) => a.label.localeCompare(b.label));
}
const objTree = (obj) => {
  return short(
    Object.keys(obj).map((e) => {
      var isObj =
        Object.prototype.toString.call(obj[e]).slice(8, -1).toLowerCase() == "object";
      return { label: e, children: isObj ? objTree(obj[e]) : [], isLeaf: !isObj };
    })
  );
};
const jsDoc = (obj) => {
  return short(
    Object.getOwnPropertyNames(
      obj == Number || obj == Math || obj == Object || obj == _
        ? obj
        : obj.constructor.prototype
    ).map((e) => {
      return { label: e, children: [], isLeaf: true };
    })
  );
};

const domDoc = () => {
  var arr = [];
  for (var key in $("body").get(0)) {
    arr.push(key);
  }
  return short(
    arr.map((e) => {
      return { label: e, children: [], isLeaf: true };
    })
  );
};

export default {
  data() {
    return {
      cur: "javascript",
      list: "javascript,Array,String,Object,Number,Math,Date,Document,jquery,vue3,Mock,lodash".split(
        ","
      ),
      filterText: [],
      props: {
        label: "label",
        children: "children",
        isLeaf: "isLeaf",
      },
      data: (this.data = domDoc()),
    };
  },
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    },
  },

  created() {
    Object.assign(this, { service }); // 一般很少这样操作
  },
  methods: {
    changeTag(v) {
      this.cur = v;
      switch (this.cur) {
        case "javascript":
          this.data = domDoc();
          break;
        case "Array":
          this.data = jsDoc([]);
          break;
        case "String":
          this.data = jsDoc("");
          break;
        case "Object":
          this.data = jsDoc(Object);
          break;
        case "Number":
          this.data = short(jsDoc(1).concat(jsDoc(Number)));
          break;
        case "Math":
          this.data = jsDoc(Math);
          break;
        case "Document":
          this.data = jsDoc(Document.prototype);
          break;
        case "Date":
          this.data = jsDoc(new Date());
          break;
        case "jquery":
          this.data = objTree($);
          break;
        case "vue3":
          this.data = objTree(vue);
          break;
        case "Mock":
          this.data = objTree(Mock);
          break;
        case "lodash":
          this.data = jsDoc(_);
          break;
      }
      console.log(this.data);
      document.querySelector(".tree").scrollTop = 0;
    },
    filterNode(value, data) {
      if (!value) return true;
      return data.label.toLowerCase().includes(value.toLowerCase());
    },
    copy(s) {
      const textValue = document.createElement("textarea");
      document.body.appendChild(textValue);
      textValue.value = s;
      textValue.select();
      document.execCommand("copy");
      document.body.removeChild(textValue);
    }, 
  },
};
</script>
<style scoped>
.el-tag {
  margin: 2px;
  cursor: pointer;
}
.flex {
  display: flex;
  align-items: center;
}
.between {
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.tree {
  max-height: calc(100vh - 80px);
  overflow: auto;
}
::-webkit-scrollbar {
  display: none;
}
.element-tree-node-label-line {
  opacity: 0;
}
</style>
